#pragma once

#include "CanObserver.h"
#include "Windows.h"

#pragma warning(disable:4505) //warning produced by GLUT API
#include <GL/glut.h>
#pragma warning(default:4505)

#include <memory>

class BlocksCan;
class Block;

class Game : public CanObserver
{
public:
	Game();

	void Draw();
	void KeyPressed(int specialKey, unsigned char key, int x, int y);

	void Pause();
	void Restart();
	void Stop();
	void Update();

	virtual void ReportLoseState();
	virtual void ReportLinesRemoval(unsigned numberOf);

	static unsigned Interval();

private:
	void _SpeedUp();
	void _SpeedDown();

private:
	void _DrawCan(unsigned x0, unsigned y0, unsigned& x0new, unsigned& y0new);
	void _DrawGrid(unsigned x0, unsigned y0, unsigned vLines, unsigned hLines, unsigned step);
	void _DrawBorder(unsigned x0, unsigned y0, unsigned width, unsigned height);
	void _DrawCell(GLint x1, GLint y1, GLint x2, GLint y2, char color);

	void _DrawStatus(unsigned x0, unsigned y0);
	void _DrawNext(unsigned x0, unsigned y0);
	void _DrawText(unsigned x, unsigned y, void* font, char* format, ...);

private:
	void _InGameKey(int specialKey, unsigned char key);
	void _ControlKey(int specialKey, unsigned char key);

private:
	void _StartNextBlock();

private:
//game objects
	std::tr1::shared_ptr<BlocksCan>	_can;
	std::tr1::shared_ptr<Block>		_block;

	unsigned char   _nextRotIndex;
	unsigned char   _nextFigIndex;
	unsigned char   _nextColor;

private:
//game state
	unsigned		_lines;
	unsigned		_score;
	bool			_lose;
	bool			_paused;

	static unsigned	_speed;
	static unsigned _minSpeed;
	static unsigned _maxSpeed;
};